package com.example.aimultimodel.tools;

import org.springframework.ai.tool.annotation.Tool;

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.time.Duration;

/**
 * 系统信息工具类
 *
 * @author 18747
 */
public class SystemInfoTool {

    /**
     * 获取系统基本信息
     */
    @Tool(description = "获取系统基本信息,包括操作系统、Java版本、内存使用情况等")
    public String getSystemInfo() {
        OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
        RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
        Runtime runtime = Runtime.getRuntime();

        StringBuilder sb = new StringBuilder();
        sb.append("=== 系统信息 ===\n");
        sb.append("操作系统: ").append(osBean.getName()).append(" ").append(osBean.getVersion()).append("\n");
        sb.append("系统架构: ").append(osBean.getArch()).append("\n");
        sb.append("可用处理器: ").append(osBean.getAvailableProcessors()).append("核\n");
        sb.append("系统平均负载: ").append(String.format("%.2f", osBean.getSystemLoadAverage())).append("\n\n");

        sb.append("=== Java信息 ===\n");
        sb.append("Java版本: ").append(System.getProperty("java.version")).append("\n");
        sb.append("Java供应商: ").append(System.getProperty("java.vendor")).append("\n");
        sb.append("Java安装目录: ").append(System.getProperty("java.home")).append("\n");
        sb.append("JVM名称: ").append(runtimeBean.getVmName()).append("\n");
        sb.append("JVM版本: ").append(runtimeBean.getVmVersion()).append("\n\n");

        sb.append("=== 内存信息 ===\n");
        long maxMemory = runtime.maxMemory();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;

        sb.append("最大内存: ").append(formatBytes(maxMemory)).append("\n");
        sb.append("总内存: ").append(formatBytes(totalMemory)).append("\n");
        sb.append("已用内存: ").append(formatBytes(usedMemory)).append("\n");
        sb.append("空闲内存: ").append(formatBytes(freeMemory)).append("\n");
        sb.append("内存使用率: ").append(String.format("%.2f%%", (usedMemory * 100.0 / totalMemory))).append("\n\n");

        sb.append("=== 运行时信息 ===\n");
        long uptime = runtimeBean.getUptime();
        sb.append("JVM运行时长: ").append(formatDuration(uptime)).append("\n");
        sb.append("启动时间: ").append(new java.util.Date(runtimeBean.getStartTime())).append("\n");

        return sb.toString();
    }

    /**
     * 获取内存使用情况
     */
    @Tool(description = "获取JVM内存使用情况的详细信息")
    public String getMemoryInfo() {
        Runtime runtime = Runtime.getRuntime();

        long maxMemory = runtime.maxMemory();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        long availableMemory = maxMemory - usedMemory;

        StringBuilder sb = new StringBuilder();
        sb.append("=== JVM内存详情 ===\n");
        sb.append("最大可用内存: ").append(formatBytes(maxMemory)).append("\n");
        sb.append("当前已分配内存: ").append(formatBytes(totalMemory)).append("\n");
        sb.append("已使用内存: ").append(formatBytes(usedMemory)).append("\n");
        sb.append("空闲内存: ").append(formatBytes(freeMemory)).append("\n");
        sb.append("可用内存: ").append(formatBytes(availableMemory)).append("\n");
        sb.append("内存使用率: ").append(String.format("%.2f%%", (usedMemory * 100.0 / maxMemory))).append("\n");

        return sb.toString();
    }

    /**
     * 获取系统属性
     */
    @Tool(description = "获取指定的系统属性值,参数为属性名称。常用属性: user.home, user.dir, java.version等")
    public String getSystemProperty(String propertyName) {
        try {
            String value = System.getProperty(propertyName);
            if (value == null) {
                return "系统属性 '" + propertyName + "' 不存在";
            }
            return propertyName + " = " + value;
        } catch (SecurityException e) {
            return "无权限访问系统属性: " + propertyName;
        }
    }

    /**
     * 获取环境变量
     */
    @Tool(description = "获取指定的环境变量值,参数为变量名称。例如: PATH, JAVA_HOME等")
    public String getEnvironmentVariable(String variableName) {
        String value = System.getenv(variableName);
        if (value == null) {
            return "环境变量 '" + variableName + "' 不存在";
        }
        return variableName + " = " + value;
    }

    /**
     * 触发垃圾回收
     */
    @Tool(description = "建议JVM执行垃圾回收(不保证立即执行)")
    public String suggestGarbageCollection() {
        Runtime runtime = Runtime.getRuntime();
        long beforeFree = runtime.freeMemory();

        System.gc();

        try {
            Thread.sleep(100); // 等待GC完成
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        long afterFree = runtime.freeMemory();
        long freed = afterFree - beforeFree;

        return String.format("已建议执行垃圾回收\n" +
                        "回收前空闲内存: %s\n" +
                        "回收后空闲内存: %s\n" +
                        "释放内存: %s",
                formatBytes(beforeFree),
                formatBytes(afterFree),
                formatBytes(freed));
    }

    /**
     * 格式化字节数为可读格式
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        char pre = "KMGTPE".charAt(exp - 1);
        return String.format("%.2f %sB", bytes / Math.pow(1024, exp), pre);
    }

    /**
     * 格式化时长
     */
    private String formatDuration(long millis) {
        Duration duration = Duration.ofMillis(millis);
        long days = duration.toDays();
        long hours = duration.toHoursPart();
        long minutes = duration.toMinutesPart();
        long seconds = duration.toSecondsPart();

        if (days > 0) {
            return String.format("%d天 %d小时 %d分钟 %d秒", days, hours, minutes, seconds);
        } else if (hours > 0) {
            return String.format("%d小时 %d分钟 %d秒", hours, minutes, seconds);
        } else if (minutes > 0) {
            return String.format("%d分钟 %d秒", minutes, seconds);
        } else {
            return String.format("%d秒", seconds);
        }
    }
}
